package com.ruoyi.wvp.service.impl;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.wvp.domain.AddressUnit;
import com.ruoyi.wvp.domain.Surveillance;
import com.ruoyi.wvp.service.IAddressUnitService;
import com.ruoyi.wvp.service.ISurveillanceService;
import com.ruoyi.wvp.utils.PermissionUtil;
import jakarta.validation.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.wvp.mapper.CardReaderMapper;
import com.ruoyi.wvp.domain.CardReader;
import com.ruoyi.wvp.service.ICardReaderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.enums.DeletedEnum;
import com.ruoyi.common.utils.StringUtils;

import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 读卡器Service业务层处理
 *
 * @author ruoyi
 * @date 2024-07-29
 */
@Service
@Slf4j
public class CardReaderServiceImpl extends ServiceImpl<CardReaderMapper, CardReader> implements ICardReaderService {
    @Autowired
    private CardReaderMapper cardReaderMapper;
    @Autowired
    private IAddressUnitService addressUnitService;
    @Autowired
    protected Validator validator;

    /**
     * 查询读卡器
     *
     * @param id 读卡器主键
     * @return 读卡器
     */
    @Override
    public CardReader selectCardReaderById(Long id) {
        return cardReaderMapper.selectCardReaderById(id);
    }

    /**
     * 查询读卡器列表
     *
     * @param cardReader 读卡器
     * @return 读卡器
     */
    @Override
    public List<CardReader> selectCardReaderList(CardReader cardReader) {
        return cardReaderMapper.selectCardReaderList(cardReader);
    }

    /**
     * 新增读卡器
     *
     * @param cardReader 读卡器
     * @return 结果
     */
    @Override
    public int insertCardReader(CardReader cardReader) {
        cardReader.setCreateTime(DateUtils.getNowDate());
        return cardReaderMapper.insertCardReader(cardReader);
    }

    /**
     * 修改读卡器
     *
     * @param cardReader 读卡器
     * @return 结果
     */
    @Override
    public int updateCardReader(CardReader cardReader) {
        cardReader.setUpdateTime(DateUtils.getNowDate());
        return cardReaderMapper.updateCardReader(cardReader);
    }

    /**
     * 批量删除读卡器
     *
     * @param ids 需要删除的读卡器主键
     * @return 结果
     */
    @Override
    public int deleteCardReaderByIds(Long[] ids) {
        return cardReaderMapper.deleteCardReaderByIds(ids);
    }

    /**
     * 删除读卡器信息
     *
     * @param id 读卡器主键
     * @return 结果
     */
    @Override
    public int deleteCardReaderById(Long id) {
        return cardReaderMapper.deleteCardReaderById(id);
    }


    @Override
    public Page<CardReader> pageList(Page<CardReader> page, CardReader cardReader) {
        LambdaQueryWrapper<CardReader> queryWrapper = getQueryWrapper(cardReader);
        return page(page, queryWrapper);
    }

    @Override
    public List<CardReader> listAll(CardReader cardReader) {
        return list(getQueryWrapper(cardReader));
    }

    private LambdaQueryWrapper<CardReader> getQueryWrapper(CardReader cardReader) {
        LambdaQueryWrapper<CardReader> queryWrapper = Wrappers.lambdaQuery(CardReader.class);
        queryWrapper.eq(CardReader::getDeleted, DeletedEnum.NOMAL.getValue());

        Long deptId = SecurityUtils.getDeptId();
        String sql = PermissionUtil.getDeptAddressUnitSql(deptId);
        queryWrapper.inSql(CardReader::getCommunityCode,sql);
//        设备品牌
        if (StringUtils.isNotEmpty(cardReader.getDeviceBrand())) {
            queryWrapper.like(CardReader::getDeviceBrand, cardReader.getDeviceBrand());
        }


//        设备型号
        if (StringUtils.isNotEmpty(cardReader.getDeviceModel())) {
            queryWrapper.like(CardReader::getDeviceModel, cardReader.getDeviceModel());
        }


//        设备状态 1 在线 0 离线
        if (Objects.nonNull(cardReader.getDeviceStatus())) {
            queryWrapper.eq(CardReader::getDeviceStatus, cardReader.getDeviceStatus());
        }


//        设备名称
        if (StringUtils.isNotEmpty(cardReader.getDeviceName())) {
            queryWrapper.like(CardReader::getDeviceName, cardReader.getDeviceName());
        }


//        设备序列号
        if (StringUtils.isNotEmpty(cardReader.getSerialNumber())) {
            queryWrapper.like(CardReader::getSerialNumber, cardReader.getSerialNumber());
        }


//        省份名称
        if (StringUtils.isNotEmpty(cardReader.getProviceName())) {
            queryWrapper.like(CardReader::getProviceName, cardReader.getProviceName());
        }


//        省份编码
        if (StringUtils.isNotEmpty(cardReader.getProviceCode())) {
            queryWrapper.eq(CardReader::getProviceCode, cardReader.getProviceCode());
        }


//        市名称
        if (StringUtils.isNotEmpty(cardReader.getCityName())) {
            queryWrapper.like(CardReader::getCityName, cardReader.getCityName());
        }


//        市编号
        if (StringUtils.isNotEmpty(cardReader.getCityCode())) {
            queryWrapper.eq(CardReader::getCityCode, cardReader.getCityCode());
        }


//        区名称
        if (StringUtils.isNotEmpty(cardReader.getAreaName())) {
            queryWrapper.like(CardReader::getAreaName, cardReader.getAreaName());
        }


//        区编码
        if (StringUtils.isNotEmpty(cardReader.getAreaCode())) {
            queryWrapper.eq(CardReader::getAreaCode, cardReader.getAreaCode());
        }


//        地址
        if (StringUtils.isNotEmpty(cardReader.getAddress())) {
            queryWrapper.like(CardReader::getAddress, cardReader.getAddress());
        }


//        社区
        if (StringUtils.isNotEmpty(cardReader.getCommunity())) {
            queryWrapper.like(CardReader::getCommunity, cardReader.getCommunity());
        }


//        小区名称
        if (StringUtils.isNotEmpty(cardReader.getResidentialName())) {
            queryWrapper.like(CardReader::getResidentialName, cardReader.getResidentialName());
        }


//        ip
        if (StringUtils.isNotEmpty(cardReader.getIp())) {
            queryWrapper.eq(CardReader::getIp, cardReader.getIp());
        }


//        物理地址
        if (StringUtils.isNotEmpty(cardReader.getMacAddress())) {
            queryWrapper.eq(CardReader::getMacAddress, cardReader.getMacAddress());
        }


//        投放点
        if (StringUtils.isNotEmpty(cardReader.getPlacement())) {
            queryWrapper.like(CardReader::getPlacement, cardReader.getPlacement());
        }


//        登记时间
        if (Objects.nonNull(cardReader.getRegisterTime())) {
            queryWrapper.eq(CardReader::getRegisterTime, cardReader.getRegisterTime());
        }


//        接入状态
        if (Objects.nonNull(cardReader.getAccessStatus())) {
            queryWrapper.eq(CardReader::getAccessStatus, cardReader.getAccessStatus());
        }


//        接入时间
        if (Objects.nonNull(cardReader.getAccessTime())) {
            queryWrapper.eq(CardReader::getAccessTime, cardReader.getAccessTime());
        }


//        街道名称
        if (StringUtils.isNotEmpty(cardReader.getStreetName())) {
            queryWrapper.like(CardReader::getStreetName, cardReader.getStreetName());
        }


//        街道id
        if (StringUtils.isNotEmpty(cardReader.getStreetCode())) {
            queryWrapper.eq(CardReader::getStreetCode, cardReader.getStreetCode());
        }


        if(Objects.nonNull(cardReader.getPushType())){
            queryWrapper.eq(CardReader::getPushType, cardReader.getPushType());
        }

        return queryWrapper;
    }




    @Override
    public String importCareRedar(List<CardReader> list, boolean isUpdateSupport, String operName) {
        if (StringUtils.isNull(list) || list.size() == 0) {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();


        List<AddressUnit> addressUnits = addressUnitService.listAll(new AddressUnit());
        Map<String, Long> addressUnitMap = addressUnits.stream().collect(Collectors.toMap(AddressUnit::getName, AddressUnit::getId));
        for (
                CardReader item : list) {
            try {
                // 验证是否存在这个读卡器
                CardReader u = getBySerialNumber(item.getSerialNumber());
                if (StringUtils.isNull(u)) {
                    BeanValidators.validateWithException(validator, item);
                    //设置区域编号和街道编号
                    setAreaCodeAndStreetCode(item, addressUnitMap);
                    item.setCreateBy(operName);
                    item.setSerialNumber(item.getSerialNumber());
                    item.setCreateTime(new Date());
                    item.setEditTime(LocalDateTime.now());
                    item.setRegisterTime(LocalDateTime.now());
                    item.setAccessTime(LocalDateTime.now());
                    item.setUpdateBy(operName);
                    item.setUpdateTime(new Date());
                    save(item);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、设备序列号 " + item.getSerialNumber() + " 导入成功");
                } else if (isUpdateSupport) {
                    BeanValidators.validateWithException(validator, item);
                    item.setId(u.getId());
                    item.setUpdateBy(operName);
                    item.setUpdateTime(new Date());
                    //设置区域编号和街道编号
                    setAreaCodeAndStreetCode(item, addressUnitMap);
                    updateById(item);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、设备序列号 " + item.getSerialNumber() + " 更新成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、设备序列号 " + item.getSerialNumber() + " 已存在");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、设备序列号 " + item.getSerialNumber() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    private CardReader getBySerialNumber(String serialNumber) {
        Wrapper<CardReader> query=Wrappers.lambdaQuery(CardReader.class)
                .eq(CardReader::getSerialNumber, serialNumber)
                .eq(CardReader::getDeleted, DeletedEnum.NOMAL.getValue());
        return getOne(query,false);
    }

    private static void setAreaCodeAndStreetCode(CardReader item, Map<String, Long> addressUnitMap) {
        Long areaCode = addressUnitMap.get(item.getAreaName());
        if (Objects.nonNull(areaCode)) {
            item.setAreaCode(areaCode.toString());
        }
        Long streetCode = addressUnitMap.get(item.getStreetName());
        if (Objects.nonNull(streetCode)) {
            item.setStreetCode(streetCode.toString());
        }
        Long communityCode = addressUnitMap.get(item.getCommunity());
        if(Objects.nonNull(communityCode)) {
            item.setCommunityCode(communityCode.toString());
        }
        Long residentialCode = addressUnitMap.get(item.getResidentialName());
        if(Objects.nonNull(residentialCode)) {
            item.setResidentialCode(residentialCode.toString());
        }
    }
}
